package cn.ujn.medicalbackend.service.impl;

import cn.ujn.medicalbackend.common.ErrorCode;
import cn.ujn.medicalbackend.domain.Account;
import cn.ujn.medicalbackend.domain.Doctor;
import cn.ujn.medicalbackend.domain.DoctorLevel;
import cn.ujn.medicalbackend.domain.TreatType;
import cn.ujn.medicalbackend.exception.BusinessException;
import cn.ujn.medicalbackend.mapper.DoctorMapper;
import cn.ujn.medicalbackend.request.DoctorAddRequest;
import cn.ujn.medicalbackend.request.DoctorDeleteRequest;
import cn.ujn.medicalbackend.request.DoctorUpdateRequest;
import cn.ujn.medicalbackend.service.AccountService;
import cn.ujn.medicalbackend.service.DoctorLevelService;
import cn.ujn.medicalbackend.service.DoctorService;
import cn.ujn.medicalbackend.service.TreatTypeService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.ujn.medicalbackend.constant.AccountConstant.ADMIN_ROLE;
import static cn.ujn.medicalbackend.constant.AccountConstant.DOCTOR_ROLE;

/**
 * @author 26532
 * @description 针对表【doctor】的数据库操作Service实现
 * @createDate 2024-10-24 17:48:58
 */
@Service
public class DoctorServiceImpl extends ServiceImpl<DoctorMapper, Doctor>
        implements DoctorService {
    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "xincheng";

    @Autowired
    private DoctorLevelService doctorLevelService;

    @Autowired
    private TreatTypeService treatTypeService;

    @Autowired
    private AccountService accountService;


    @Override
    public Page<Doctor> DoctorPageTransfer(Page<Doctor> tempPage) {
        for (Doctor doctor : tempPage.getRecords()) {
            long doctorLevelId = doctor.getLevelId();
            DoctorLevel doctorLevelTemp = doctorLevelService.getById(doctorLevelId);
            doctor.setDoctorLevel(doctorLevelTemp.getName());
            long treatTypeId = doctor.getTypeId();
            TreatType treatTypeTemp = treatTypeService.getById(treatTypeId);
            doctor.setThreatType(treatTypeTemp.getName());
        }
        return tempPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long addDoctor(DoctorAddRequest doctorAddRequest, HttpServletRequest request) {
        Account loginAccount = accountService.getLoginAccount(request);
        // 1.请求参数是否是空
        if (doctorAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 2.是否登录
        if (loginAccount == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        Doctor doctor = new Doctor();
        BeanUtils.copyProperties(doctorAddRequest, doctor);
        Date now = new Date();
        doctor.setCreatetime(now);
        doctor.setUpdatetime(now);
        // 鉴权，只有管理员可创建
        boolean isAdmin = accountService.isAdmin(request);
        if (!isAdmin) {
            throw new BusinessException(ErrorCode.NO_AUTH, "只有管理员有权限进行添加");
        }

        // 3.校验信息
        if (doctor.getName() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "姓名不能为空");
        }
        // 账户不能有特殊字符
        String validPattern = "^[u4e00-u9fa5]{2,4}";
        Matcher matcher = Pattern.compile(validPattern).matcher(doctor.getName());
        if (matcher.find()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "姓名只能为汉字，且长度为2-4个汉字");
        }
        if (doctor.getAge() == null || doctor.getAge() < 1 || doctor.getAge() > 130) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "年龄不能为空或格式错误");
        }
        if (doctor.getSex() == null || (doctor.getSex() != 1 && doctor.getSex() != 2)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "性别不能为空或性别错误，1代表男，2代表女");
        }
        if (doctor.getLevelId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "等级不能为空");
        }
        if (doctor.getPhone() == null || doctor.getPhone().length() != 11) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号不能为空或手机号格式错误");
        }
        if (doctor.getTypeId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "级别不能为空");
        }
        if (doctorAddRequest.getUname() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名不能为空");
        }
        if (doctorAddRequest.getPwd() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码不能为空");
        }
        String utype = doctorAddRequest.getUtype();
        if (utype == null || (!utype.equals(ADMIN_ROLE) && !utype.equals(DOCTOR_ROLE))) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "角色类型不能为空,角色类型：ROLE_1 管理员，ROLE_2 医生");
        }
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uname", doctorAddRequest.getUname());
        long count = accountService.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名重复！");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + doctorAddRequest.getPwd()).getBytes());


        boolean result;
        Account account = new Account();
        BeanUtils.copyProperties(doctorAddRequest, account);
        account.setPwd(encryptPassword);
        account.setRealname(doctorAddRequest.getName());
        account.setPhonenumber(doctorAddRequest.getPhone());
        account.setCreatetime(now);
        account.setUpdatetime(now);
        result = accountService.save(account);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建医师失败");
        }
        doctor.setAccountId(account.getId());
        result = this.save(doctor);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建医师失败");
        }
        return doctor.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDoctor(DoctorDeleteRequest doctorDeleteRequest, HttpServletRequest request) {
        // 鉴权，只有管理员可创建
        boolean isAdmin = accountService.isAdmin(request);
        if (!isAdmin) {
            throw new BusinessException(ErrorCode.NO_AUTH, "只有管理员有权限进行添加");
        }

        Long doctorId = doctorDeleteRequest.getId();
        String AccountUname = doctorDeleteRequest.getUname();
        Long AccountID = doctorDeleteRequest.getAccountId();

        if (doctorId == null || (AccountUname == null&&AccountID==null)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "；医生id和(账户名或者账户id)不能为空");
        }

        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("uname", AccountUname);
        queryWrapper.eq("id",AccountID);
        long count = accountService.count(queryWrapper);
        if (count <= 0) {
            throw new BusinessException(ErrorCode.NULL_ERROR, "没有该账户");
        }
        Account account = new Account();
        account = accountService.getOne(queryWrapper);

        QueryWrapper<Doctor> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("id", doctorId);
        long count1 = this.count(queryWrapper1);
        if (count1 <= 0) {
            throw new BusinessException(ErrorCode.NULL_ERROR, "没有该医师");
        }
        boolean result = this.removeById(doctorId);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除失败");
        }
        result = accountService.removeById(account.getId());

        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除失败");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDoctor(DoctorUpdateRequest doctorUpdateRequest, HttpServletRequest request) {
        if (doctorUpdateRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Account loginAccount = accountService.getLoginAccount(request);
        if (loginAccount == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        if (!accountService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH);
        }
        Date now = new Date();
        Doctor doctor = this.getById(doctorUpdateRequest.getId());
        BeanUtils.copyProperties(doctorUpdateRequest, doctor);
        doctor.setUpdatetime(now);
        Account account = accountService.getById(doctorUpdateRequest.getAccountId());
        BeanUtils.copyProperties(doctorUpdateRequest, account);
        account.setId(doctorUpdateRequest.getAccountId());
        account.setRealname(doctorUpdateRequest.getName());
        account.setPhonenumber(doctorUpdateRequest.getPhone());
        account.setUpdatetime(now);
        System.out.println("11111 " + doctor);
        System.out.println("22222 " + account);

        boolean result = accountService.updateById(account);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新失败");
        }
        result = this.updateById(doctor);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新失败");
        }

        return true;
    }

    @Override
    public List<Doctor> doctorListTransfer(List<Doctor> doctorList) {
        for (Doctor doctor : doctorList) {
            long doctorLevelId = doctor.getLevelId();
            DoctorLevel doctorLevelTemp = doctorLevelService.getById(doctorLevelId);
            doctor.setDoctorLevel(doctorLevelTemp.getName());
            long treatTypeId = doctor.getTypeId();
            TreatType treatTypeTemp = treatTypeService.getById(treatTypeId);
            doctor.setThreatType(treatTypeTemp.getName());
        }
        return doctorList;
    }

}




